import { globalEmitter, activeEmitter } from '@/App'
import { isKeyboardCombination } from '@/utils/keyboard'
import { SerializableObject, ToolName } from '../public';
import type { AppDispatch } from '@/store';
import { SerializableToolObject } from '@/reducers/toolSlice';
import { ReactNode } from 'react';


type KeyCombination = `${'Ctrl' | 'Alt' | 'Shift'}+${string}` | `${string}`;
type EventLfeCycle = 'global' | undefined



export default abstract class ToolBase {
  static ToolItem?: React.FC<SerializableToolObject>
  static Params?: React.FC<SerializableToolObject>
  abstract name: ToolName
  abstract label: string
  abstract description: string
  abstract serialize(): SerializableObject  // 序列化
  abstract onActive(dispatch: AppDispatch): void  // 激活
  abstract onInActive(dispatch: AppDispatch): void  // 失活

  constructor(){
  }

  /**
   * @description: 订阅事件
   * @param {KeyCombination} typeCombination 事件:组合键 例如 keyup:Ctrl+V
   * @param {(...args: any[]) => void} eventAction 触发事件
   * @param {EventLfeCycle} eventLfeCycle 可选参数 'global' | undefined，事件生命周期，默认为当前类，global为全局事件
   * @return {*}
   */  
  protected subscribe(typeCombination: KeyCombination, eventAction: (...args: any[]) => void, eventLfeCycle?: EventLfeCycle){
    const thisEmitter = eventLfeCycle == 'global' ? globalEmitter : activeEmitter;
    let [eventName, shortcut] = typeCombination.split(/\s*:\s*/);
    let lowerCaseEventName = eventName.toLocaleLowerCase()
    
    thisEmitter.on(lowerCaseEventName, (e: Event) => {
      if(lowerCaseEventName == 'keydown' || lowerCaseEventName == 'keyup'){
        const keyboardEvent = e as KeyboardEvent;
        if(isKeyboardCombination(keyboardEvent, shortcut)) eventAction(e)
      }
      else {
        eventAction(e)
      }
    })
  }

  /**
   * @description: 注销所有订阅事件（不包括全局事件）
   * @return {void}
   */  
  protected unsubscribe(){
    activeEmitter.disconnect()
  }

}